import json

from PySide6.QtCore import QDateTime
from Devices.Chiot.ChiotDevice import ChiotDevice

class ChiotDeviceParser(object):
    def PackBase(obj, msgvalue, msgName):
        msgvalue["traceId"] = "12345678"

        data = {}
        data["msgname"] = msgName
        data["msgvalue"] = msgvalue

        obj["data"] = data
        obj["client"] = "NetWorkTestTool"
        obj["time"] = QDateTime.currentMSecsSinceEpoch()
        return obj

    def PackAttr(msgvalue, attrName, propertyName, propertyValue):
        attr = {}
        properties = {}
        if attrName in msgvalue:
            attr = msgvalue[attrName]
            properties = attr["properties"]

        properties[propertyName] = propertyValue
        attr["properties"] = properties
        msgvalue[attrName] = attr

    def PackSetTimer(timer):
        timer_json = {}
        timer_json["id"] = timer.id
        timer_json["enable"] = 1 if timer.enable else 0

        services = []
        for i in range(len(timer.services)):
            service = {}
            service["serviceId"] = timer.services[i].serviceId
            service["para"] = timer.services[i].para
            service["paraValue"] = int(timer.services[i].paraValue)
            services.append(service)
        timer_json["services"] = services
        timer_json["start"] = timer.start
        timer_json["end"] = timer.end
        timer_json["week"] = timer.week

        timers_json = []
        timers_json.append(timer_json)

        msgvalue = {}
        msgvalue["timer"] = timers_json
        obj = {}
        jsonDoc = ChiotDeviceParser.PackBase(obj, msgvalue, "setTimer")
        return json.dumps(jsonDoc, separators=(',', ':'))

    def PackSetDelay(delay):
        delay_json = {}
        delay_json["id"] = delay.id
        delay_json["enable"] = 1 if delay.enable else 0

        services = []
        for i in range(len(delay.services)):
            service = {}
            service["serviceId"] = delay.services[i].serviceId
            service["para"] = delay.services[i].para
            service["paraValue"] = int(delay.services[i].paraValue)
            services.append(service)

        delay_json["services"] = services
        delay_json["start"] = delay.start
        delay_json["end"] = delay.end

        msgvalue = {}
        msgvalue["delay"] = delay_json
        obj = {}
        jsonDoc = ChiotDeviceParser.PackBase(obj, msgvalue, "setDelay")
        return json.dumps(jsonDoc, separators=(',', ':'))

    def PackSetTimezone(timezone):
        msgvalue = {}
        msgvalue["timezone"] = timezone

        obj = {}
        jsonDoc = ChiotDeviceParser.PackBase(obj, msgvalue, "heartbeatResponse")
        return json.dumps(jsonDoc, separators=(',', ':'))

    def PackUpgrade(upgradePackageId, downloadUrl, mac, newVersion, md5, size):
        msgvalue = {}
        msgvalue["upgradePackageId"] = upgradePackageId
        msgvalue["downloadUrl"] = downloadUrl
        msgvalue["mac"] = mac
        msgvalue["newVersion"] = newVersion
        msgvalue["md5"] = md5
        msgvalue["size"] = size
        msgvalue["otaReportFreq"] = "5"
        msgvalue["update"] = True

        obj = {}
        jsonDoc = ChiotDeviceParser.PackBase(obj, msgvalue, "update")
        return json.dumps(jsonDoc, separators=(',', ':'))

    def PackUnbind():
        msgvalue = {}
        msgvalue["isClean"] = 0

        obj = {}
        jsonDoc = ChiotDeviceParser.PackBase(obj, msgvalue, "unbinding")
        return json.dumps(jsonDoc, separators=(',', ':'))

    def PackGetFullStatus():
        obj = {}
        obj["client"] = "TEST"
        obj["cmd"] = "getFullStatus"

        return json.dumps(obj, separators=(',', ':'))

    def __GetTheProperty(obj, propertyName):
        if not propertyName in obj:
            return (False, None)

        value = obj[propertyName]
        return (True, value)

    def __GetAttrProperty(obj, attrName, propertyName):
        if not attrName in obj:
            return (False, None)

        attr = obj[attrName]
        if not "properties" in attr:
            return (False, None)

        oneProperty = attr["properties"]
        if not propertyName in oneProperty:
            return (False, None)

        value = oneProperty[propertyName]
        return (True, value)

    def GetStrProperty(obj, *args):
        if (1 == len(args)):
            ret, strVal = ChiotDeviceParser.__GetTheProperty(obj, args[0])
        elif (len(args) > 1):
            ret, strVal = ChiotDeviceParser.__GetAttrProperty(obj, args[0], args[1])
        
        if ret:
            return (True, str(strVal))
        else:
            return (False, "")

    def GetIntProperty(obj, *args):
        if (1 == len(args)):
            ret, intVal = ChiotDeviceParser.__GetTheProperty(obj, args[0])
        elif (len(args) > 1):
            ret, intVal = ChiotDeviceParser.__GetAttrProperty(obj, args[0], args[1])
        
        if ret:
            return (True, int(intVal))
        else:
            return (False, 0)

    def GetServices(obj, attrName):
        if not attrName in obj:
            return (False, None)

        services = obj[attrName]
        serviceList = []
        for i in range(len(services)):
            if services[i] is None:
                return (False, None)
            service = services[i]
            if (not "serviceId" in service) or (not "para" in service) or (not "paraValue" in service):
                return (False, None)

            sp = ChiotDevice.ServiceParams(service["serviceId"], service["para"], int(service["paraValue"]))
            serviceList.append(sp)

        return (True, serviceList)

    def GetTimers(obj, attrName, timerList):
        if not attrName in obj:
            return False

        timerList.clear()
        timers = obj[attrName]
        for i in range(len(timers)):
            if timers[i] is None:
                return False
            service = timers[i]

            if (not "id" in service) or (not "enable" in service) or (not "start" in service) or (not "end" in service) or (not "services" in service) or (not "week" in service):
                return False
            ret, serviceList = ChiotDeviceParser.GetServices(service, "services")
            if not ret:
                return False

            timer = ChiotDevice.Timer(service["id"], bool(service["enable"]), service["start"], service["end"], serviceList, int(service["week"]))
            timerList.append(timer)

        return True

    def GetDelay(obj, attrName, delay):
        if not attrName in obj:
            return False

        delay.Reset()
        delayJson = obj[attrName]
        if isinstance(delayJson, list):
            delayJson = delayJson[0]

        if (not "id" in delayJson) or (not "enable" in delayJson) or (not "start" in delayJson) or (not "end" in delayJson) or (not "services" in delayJson):
            return False

        delay.id = delayJson["id"]
        delay.enable = delayJson["enable"]
        delay.start = delayJson["start"]
        delay.end = delayJson["end"]

        ret, serviceList = ChiotDeviceParser.GetServices(delayJson, "services")
        if not ret:
            return False
        delay.services = serviceList

        return True

    def ParseMsg(data):
        doc = json.loads(data)
        if doc is None:
            return (False, None, None)

        if not "data" in doc:
            return (False, None, None)

        dataObj = doc["data"]
        if not "msgname" in dataObj:
            return (False, None, None)

        msgName = dataObj["msgname"]

        if not "msgvalue" in dataObj:
            return (False, None, None)

        msgValue = dataObj["msgvalue"]

        return (True, msgName, msgValue)

    def ParseOtaProcess(msgValue, otaProcess):
        if not "stateValue" in msgValue:
            return False
        stateValue = msgValue["stateValue"]

        ret, strValue = ChiotDeviceParser.GetStrProperty(stateValue, "startTime")
        if ret:
            otaProcess.startTime = strValue

        ret, strValue = ChiotDeviceParser.GetStrProperty(stateValue, "totalTime")
        if ret:
            otaProcess.totalTime = strValue

        ret, strValue = ChiotDeviceParser.GetStrProperty(stateValue, "process")
        if ret:
            otaProcess.process = strValue

        ret, strValue = ChiotDeviceParser.GetStrProperty(stateValue, "progress")
        if ret:
            otaProcess.progress = strValue

        ret, strValue = ChiotDeviceParser.GetStrProperty(stateValue, "frequency")
        if ret:
            otaProcess.frequency = strValue

        return True
    
    def ParseOtaResult(msgValue, otaResult):
        if not "stateValue" in msgValue:
            return False
        stateValue = msgValue["stateValue"]

        ret, strValue = ChiotDeviceParser.GetStrProperty(stateValue, "result")
        if ret:
            otaResult.result = strValue

        ret, strValue = ChiotDeviceParser.GetStrProperty(stateValue, "firmwareVersion")
        if ret:
            otaResult.firmwareVersion = strValue

        ret, strValue = ChiotDeviceParser.GetStrProperty(stateValue, "hardwareVersion")
        if ret:
            otaResult.hardwareVersion = strValue

        ret, strValue = ChiotDeviceParser.GetStrProperty(stateValue, "upgradePackageUuid")
        if ret:
            otaResult.upgradePackageUuid = strValue

        return True
    


